package com.nb.algor;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author lihaoyang
 * @date 2023/3/17
 */
public class LRUCache<K, V> extends LinkedHashMap<K, V>{
    /**
     * 初始缓存大小
     */
    private final int CACHE_SIZE;
    /**
     * 初始化缓存，并设置大小
     *
     * @param cacheSize 缓存大小
     */
    public LRUCache(int cacheSize) {
        //初始化一个LinkedHashMap，true表示按照访问顺序来进行排序，最近访问的数据放在尾部，最老访问的放在头部
        super((int) Math.ceil((cacheSize / 0.75) + 1), 0.75f, true);
        this.CACHE_SIZE = cacheSize;
    }

    /**
     * 是否移除最久没被访问的那个节点
     *
     * @return 是否满足删除条件
     */
    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        //判断现在map中的数量是否达到了指定的缓存数
        //在调用put方法的时候，会调用这个方法，如果达到了缓存的大小，删掉最长时间没被访问的entry
        return size() > CACHE_SIZE;
    }


    public static void main(String[] args) {
        /**
         * 初始化一个容量大小为10的LRU缓存
         */
         LRUCache<String, Integer> lruCache = new LRUCache<>(8);
        //往缓存中加10个数，加入之后，缓存现在已经满了
        for (int i = 0; i < 8; i++) {
            lruCache.put("k" + i, i);
        }
        //先看看现在缓存中的情况
        System.err.println("all cache:"+lruCache);

        //先访问一次k3
        lruCache.get("k3");
        System.err.println("get k3之后:"+lruCache);

        //在访问一次k4
        lruCache.get("k4");
        System.err.println("get k4之后:"+ lruCache);

        //往容量已经满了的缓存中再加一个数k10,看看谁被淘汰了
        lruCache.put("k10", 10);
        System.err.println("put k10之后:"+ lruCache);


    }
}
